package com.easidea.tim.service.customer;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springside.core.service.EntityService;

import com.easidea.tim.dao.customer.CustomerDao;
import com.easidea.tim.dao.saleorder.SaleOrderDao;
import com.easidea.tim.dao.system.orgnization.StaffDAO;
import com.easidea.tim.entity.customer.Customer;
import com.easidea.tim.entity.saleorder.SaleOrder;
import com.easidea.tim.util.Page;

/**
 * 
 * @Title: CustomerSevice.java
 * @Package com.easidea.tim.service.system.customer
 * @Description: TODO
 * @author gavin.shao 
 * @Email gaivn.shao@infowarelab.com
 * @date 2009-10-13 下午04:20:05
 * @version V1.0
 */
public class CustomerService extends EntityService<Customer, CustomerDao> {
	private CustomerDao customerDao;
	private StaffDAO staffDao;
	private SaleOrderDao saleOrderDao;

	@SuppressWarnings("unchecked")
	public Page getCustomerListByCondition(String name, long areaId, String contactor, String salesName, Page page, Long loginUserId) {
		 Criteria ca = getCustomerListByConditionCriteria(name, areaId, contactor, salesName, loginUserId);
		 ca.setProjection(Projections.count("name"));
		 Integer totalNum = (Integer)ca.uniqueResult();
		 Criteria ca1 = getCustomerListByConditionCriteria(name, areaId, contactor, salesName, loginUserId);
		 int startIndex = Page.getStartOfPage(page.getCurrentPageNo(), page.getPageSize());
		 ca1.setFirstResult(startIndex);
		 ca1.setMaxResults(page.getPageSize());
		 List<Customer> customers = (List<Customer>)ca1.list();

		 Page resultPage = new Page(startIndex, totalNum, page.getPageSize(), customers);
		 resultPage.setCurrentPageNo(page.getCurrentPageNo());		
		
		return resultPage;

	}
	private Criteria getCustomerListByConditionCriteria(String name, long areaId, String contactor, String salesName, Long loginUserId) {
		Criteria ca = createUnDeletedCriteria();
		if(StringUtils.isNotBlank(name)) {
			ca.add(Restrictions.ilike("name", name, MatchMode.ANYWHERE));
		}
		if(areaId != -1) {
			ca.add(Restrictions.eq("area.id", areaId));
		}
		if (StringUtils.isNotBlank(contactor)) {
			ca.add(Restrictions.ilike("contactor", contactor, MatchMode.ANYWHERE));
		}
		if (StringUtils.isNotBlank(salesName)){
			ca.createAlias("staff", "staff");
			ca.add(Restrictions.ilike("staff.name", salesName.trim(), MatchMode.ANYWHERE));
		}
		
		/** added by harrison **/
//		List<String> userNames = staffDao.getTeamworkIdsByLoginUserId(loginUserId);
//		//if(userNames != null && userNames.size() > 0) {
//			ca.add(Restrictions.or(Restrictions.in("creator", userNames), Restrictions.in("modifier", userNames)));
//		//}
		List<Long> staffIds = staffDao.getTeamworkStaffIdsByLoginUserId(loginUserId);
		ca.add(Restrictions.in("staff.id", staffIds));
		/** end **/
		
		
		return ca;
	}

	public Customer getCustomerById(Long id) {
		return get(id);
	}

	private boolean hasSameName(Customer customer) {
		boolean ret = false;
		Criteria ca = createUnDeletedCriteria();
		if(customer.getName() != null && !customer.getName().equals("")) {
			ca.add(Restrictions.eq("name", customer.getName()));
			ca.add(Restrictions.eq("type.id", customer.getType().getId()));
			ca.add(Restrictions.eq("area.id", customer.getArea().getId()));
		}
		ca.add(Restrictions.ne("id", customer.getId()));
	
		if(ca.uniqueResult() != null) {
			ret = true;
		}
		return ret;
	}
	
	
	public String saveOrUpdateCustomer(Customer customer) {
		if(hasSameName(customer)) {
			return "ExistSameName";
		}
		try{
			if(customer.getId() == -1) {
				customer.setAccountSummary(0d);
				customerDao.getHibernateTemplate().save(customer);	
			}else {
				customerDao.getHibernateTemplate().update(customer);
			}
		}catch(DataAccessException de) {
			de.printStackTrace();
			return de.getMessage();
		}
		return "success";
	}
	
	
	public boolean deleteCustomer(Long id){
		boolean rtn = false;
		Customer cust = this.get(id);
		if(cust != null){
			boolean hasSaleOrder = hasSaleOrderNormal(id);
			if(!hasSaleOrder){
				cust.setDeleted((short)1);
				cust.setModifyTime(new Date());
				customerDao.getHibernateTemplate().update(cust);
				rtn = true;
			}
		}
		return rtn;
	}
	
	/**
	 * 
	 * @author Harrison
	 * @param id
	 * @return
	 */
	private boolean hasSaleOrderNormal(Long id) {
		Criteria saleOrderCte = saleOrderDao.createUnDeletedCriteria();
		saleOrderCte.add(Restrictions.eq("customer.id",id));
		//saleOrderCte.add(Restrictions.lt("status", Short.valueOf(SaleOrder.order_staus_over)));
		saleOrderCte.add(Restrictions.eq("status", Short.valueOf(SaleOrder.order_staus_over)));
		saleOrderCte.setProjection(Projections.count("id"));
		Integer saleOrderCounts = (Integer)saleOrderCte.uniqueResult();
		if(saleOrderCounts > 0){
			return true;
		}else{
			return false;
		}
	}
	
	
	/**
	 * 获得应收款总额
	 * @author Harrison
	 * @return
	 */
	public Double getCustomerDuefromSummary(){
		Criteria cte = customerDao.createUnDeletedCriteria();
		cte.setProjection(Projections.sum("accountSummary"));
		Double totalSummary = (Double)cte.uniqueResult();
		cte = null;
		// 获得总的应收帐款
		return totalSummary;
	}

	/**
	 * 客户应收款
	 * 
	 * @author Harrison
	 * @param customerName
	 * @param salesName
	 * @return
	 */
	public Page listCustomerDueFromSummary(String customerName, String salesName, Page page){
		Criteria countsCte = genDuefromCriteria(customerName, salesName);
		countsCte.setProjection(Projections.count("id"));
		Integer totalCounts = (Integer)countsCte.uniqueResult(); // 记录总数
		countsCte = null;
		
		Criteria pagedCte = genDuefromCriteria(customerName, salesName);
		pagedCte.addOrder(Order.desc("accountSummary")); //根据应收款总额进行降序排列
		int startIndex = Page.getStartOfPage(page.getCurrentPageNo(), page.getPageSize());
		pagedCte.setFirstResult(startIndex);
		pagedCte.setMaxResults(page.getPageSize());
		List<Customer> customers = (List<Customer>)pagedCte.list();
		for(Customer cust: customers){
			if(cust.getStaff() != null)cust.setStaffName(cust.getStaff().getName());
		}
		pagedCte = null; 
		Page resultPage = new Page(startIndex, totalCounts, page.getPageSize(), customers);
		resultPage.setCurrentPageNo(page.getCurrentPageNo()); // 分页数据
		
		return resultPage;
	}
	private Criteria genDuefromCriteria(String customerName, String salesName) {
		Criteria cte = customerDao.createUnDeletedCriteria();
		
		if(customerName != null && customerName.trim().length()> 0){
			cte.add(Restrictions.ilike("name", "%"+customerName+"%"));
		}
		if(salesName != null && salesName.trim().length()>0){
			cte.createAlias("staff", "staff");
			cte.add(Restrictions.eq("staff.name", salesName));
		}
		return cte;
	}
	
	
	/**
	 * 保存对账信息
	 * @param id
	 * @param memo
	 * @return
	 */
	public boolean saveAccountMemo(Long id, String memo){
		if(id != null){
			Customer cus = customerDao.get(id);
			if(cus != null && cus.getName() != null){
				cus.setAccountMemo(memo);
				return true;
			}
		}
		return false;
	}
	
	
	/**
	 * 
	 * @param name
	 * @return
	 */
	public List<Customer> getCustomerListByName(String name){
		StringBuffer hqlBF = new StringBuffer("select id, name, account_summary from tim_customer_customer " +
				"where deleted = 0");
		if(name != null && name.trim().length()>0){
			hqlBF.append(" and name like '%"+name+"%'");
		}
		final String hql = hqlBF.toString();
		return (List<Customer>)customerDao.getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                SQLQuery query = session.createSQLQuery(hql);
                List<Object[]> rst = query.list();
                List<Customer> custList = new ArrayList<Customer>(rst.size());
                for(Object[] obj:rst){
                	if(obj != null){
                		Customer cust = new Customer();
                    	if(obj[0] != null)cust.setId(((BigInteger)obj[0]).longValue());
                    	if(obj[1] != null)cust.setName((String)obj[1]);
                    	if(obj[2] != null)cust.setAccountSummary(((BigDecimal)obj[2]).doubleValue());
                    	custList.add(cust);
                	}
                }
                return custList;
            }
        });
	}

	@Override
	public CustomerDao getEntityDao() {
		return customerDao;
	}
	public CustomerDao getCustomerDao() {
		return customerDao;
	}
	public void setCustomerDao(CustomerDao customerDao) {
		this.customerDao = customerDao;
	}
	public void setStaffDao(StaffDAO staffDao) {
		this.staffDao = staffDao;
	}
	/**
	 * @param saleOrderDao the saleOrderDao to set
	 */
	public void setSaleOrderDao(SaleOrderDao saleOrderDao) {
		this.saleOrderDao = saleOrderDao;
	}

	
}
